﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Animations;
using TableProto;

public class CreateCharacterEditor {

	private const string AssetPath = "Assets/Resources/main_controller";

    private static List<string> animNames = new List<string>();

    private static List<string> otherAnims = new List<string>()
    {
        "walk_p", "idell_p",
    };

	static string CharacterPath(string name) {
		string path = FileTools.CombinePath (AssetPath, name);
		FileTools.CreateDirectory (path);
		return path;
	}

	[MenuItem("工具/创建乐迪主页面动画控制器")]
	static void ClipAnimator () {
        TableProtoManager.Instance.PreLoadTableData();
        Dictionary<uint, MainAnimation> animDict = TableProtoLoader.MainAnimationDict;
        animNames.Clear();
        foreach(MainAnimation ani in animDict.Values)
        {
            foreach(MainAnimation.act_attr attr in ani.act_table)
            {
                if (!animNames.Contains(attr.act_name))
                {
                    if (attr.act_name == "all_ask" || attr.act_name == "all_talk" || attr.act_name == "all_happy" || attr.act_name == "all_talk02" || attr.act_name == "all_worry")
                    {
                        animNames.Add(attr.act_name + "_01");
                        animNames.Add(attr.act_name + "_02");
                        animNames.Add(attr.act_name + "_03");
                    }
                    else
                    {
                        animNames.Add(attr.act_name);
                    }
                }
            }
        }
        foreach(string name in otherAnims)
        {
            if (!animNames.Contains(name))
            {
                animNames.Add(name);
            }
        }

		UnityEngine.Object[] selection = Selection.GetFiltered (typeof(UnityEngine.Object), SelectionMode.DeepAssets);
		if (selection == null || selection.Length < 1)
		{
			Debug.LogError("需要选择一个模型");
			return;
		}

		string rootName = "";
		List<string> animations = new List<string> ();
		for (int i = 0; i < selection.Length; i++) {
			GameObject o = selection [i] as GameObject;

			if (o == null) {
				continue;
			}

			string assetPath = AssetDatabase.GetAssetPath (o);
			rootName = FileTools.GetFullName(FileTools.GetFullDirectory (assetPath));
			string name = o.name;

			if (!assetPath.Contains ("/ledi/"))
				continue;
			if (!assetPath.ToLower ().EndsWith (".fbx"))
				continue;

			if (name.Contains ("@")) {
				animations.Add (assetPath);
			} 
		}

		SetAnimatorPrefab (animations);

		AssetDatabase.Refresh ();
		AssetDatabase.SaveAssets(); 
		EditorUtility.DisplayDialog("提示", "完成！", "确定");
	}

	static void SetAnimatorPrefab(List<string> animations) {
		string conPath = FileTools.CombinePath (AssetPath, "ledi_main_controller.controller");

        AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(conPath);
        AnimatorControllerLayer layer = animatorController.layers[0];
		AnimatorStateMachine machine = layer.stateMachine; 
		layer.iKPass = true;

		Vector3 anyStatePosition = machine.anyStatePosition;  
		float OFFSET_X = 220;  
		float OFFSET_Y = 60;  
		float ITEM_PER_LINE = 10;  
		float originX = anyStatePosition.x + OFFSET_X;  
		float originY = anyStatePosition.y - OFFSET_Y * (ITEM_PER_LINE / 2);  
		float x = originX;  
		float y = originY;

		for (int i=0; i<animations.Count; i++) {
			ModelImporter mi = AssetImporter.GetAtPath(animations[i]) as ModelImporter;
			ModelImporterClipAnimation[] clipAnimations = mi.clipAnimations;
			foreach(ModelImporterClipAnimation clip in clipAnimations) {
				clip.loopTime = true;
			}
			mi.clipAnimations = clipAnimations;
			EditorUtility.SetDirty (mi);

			UnityEngine.Object[] objects = AssetDatabase.LoadAllAssetsAtPath(animations[i]);  
			for(int m=0;m<objects.Length;m++)  
			{  
				if(objects[m].GetType()==typeof(AnimationClip) && !objects[m].name.Contains("__preview__"))  
				{  
					AnimationClip clip=(AnimationClip)objects[m];  
					if (clip != null && animNames.Contains(clip.name)) {
						AnimatorState state = machine.AddState (clip.name, new Vector3(x, y, 0));
                        if (clip.name == "all_ask_02" || clip.name == "all_talk_02")
                        {
                            AnimationClipSettings setting = AnimationUtility.GetAnimationClipSettings(clip);
                            setting.loopTime = true;
                            AnimationUtility.SetAnimationClipSettings(clip, setting);
                        }
						state.motion = clip;
						if (clip.name == "idell_p") { //设置默认动作
							machine.defaultState = state;
						}
						y += OFFSET_Y;  
						if (y >= originY + OFFSET_Y * ITEM_PER_LINE) {  
							y = originY;  
							x += OFFSET_X;  
						} 
					}
				}  
			} 
			AssetDatabase.WriteImportSettingsIfDirty (animations[i]);
		}
	}

	static void CreatePrefab(string path, GameObject obj) {
		string prefabPath = FileTools.CombinePath (CharacterPath (path), "Actor.prefab");
		GameObject go = GameObject.Instantiate (obj) as GameObject;
		go.name = "Actor";

		ChangeLayer (go, "Player");

		go.AddComponent<ActorController> ();

		Animator animator = go.GetComponent<Animator>();  
		if (animator == null) {  
			animator = go.AddComponent<Animator>();  
		}  
		animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
		animator.applyRootMotion = false;  //使用脚本控制transform，而不是动画

		string conPath = FileTools.CombinePath (CharacterPath (path), "Animator.controller");

		AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath (conPath);
		animator.runtimeAnimatorController = animatorController;  
		PrefabUtility.CreatePrefab(prefabPath, go);  
		GameObject.DestroyImmediate(go, true);  

		AssetDatabase.SaveAssets(); 
	}

	static void ChangeLayer(GameObject go, string layer) {
		int playerLayer = UnityEngine.LayerMask.NameToLayer (layer);
		go.layer = playerLayer;
		foreach(Transform tran in go.GetComponentsInChildren<Transform>()){//遍历当前物体及其所有子物体  
			tran.gameObject.layer = playerLayer;//更改物体的Layer层  
		}  
	}
}
